﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PathAsTreeUtil
{
    public partial class Form1 : Form
    {
        private Dictionary<string, NodePath> _allNodes = new Dictionary<string, NodePath>(StringComparer.OrdinalIgnoreCase);
        private Dictionary<int, NodeLevelData> _nodeLevels = new Dictionary<int, NodeLevelData>();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var pth = Environment.GetEnvironmentVariable("PATH");

            var paths = pth.Split(Path.PathSeparator);
            foreach (var path in paths)
            {
                var dirs = path.Split(Path.DirectorySeparatorChar);
                NodePath curNode = null;
                string pathTrack = "";
                var curLevel = 0;
                foreach (var dir in dirs)
                {
                    pathTrack = Path.Combine(pathTrack, dir);
                    NodePath np = null;
                    if (!_nodeLevels.ContainsKey(curLevel))
                    {
                        _nodeLevels[curLevel] = new NodeLevelData
                            {
                                Level = curLevel,
                                Nodes = new HashSet<NodePath>()
                            };
                    }
                    if (!_allNodes.ContainsKey(pathTrack))
                    {
                        np = new NodePath
                            {
                                Node = new TreeNode(dir),
                                Path = pathTrack,
                                NodeLevel = _nodeLevels[curLevel]
                            };
                        _allNodes[pathTrack] = np;
                        if (curNode == null)
                        {
                            pathNodes.Nodes.Add(np.Node);
                        }
                        else
                        {
                            curNode.Node.Nodes.Add(np.Node);
                        }
                    }
                    else
                    {
                        np = _allNodes[pathTrack];
                    }
                    curNode = np;
                    curLevel++;
                }
            }
        }
    }

    public class NodeLevelData
    {
        public int Level { get; set; }
        public HashSet<NodePath> Nodes { get; set; }
    }

    public class NodePath
    {
        protected bool Equals(NodePath other)
        {
            return string.Equals(Path, other.Path);
        }

        public override int GetHashCode()
        {
            return (Path != null ? Path.GetHashCode() : 0);
        }

        public string Path { get; set; }
        public TreeNode Node { get; set; }
        public NodeLevelData NodeLevel { get; set; }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((NodePath) obj);
        }
    }
}
